#include <sys/socket.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/timeb.h>

void print_usage(){
  printf("Usage: multi_nc -l port\n");
  exit(1);
}

void die_error(char* msg){
  printf("Error:%s\n",msg);
  exit(1);
}

int main(int argc,char** argv){
  int port,sock;
  struct sockaddr_in addr;

  if (argc!=3||strcmp("-l",argv[1]))
    print_usage();

  sock = socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
  if (sock<0)
    die_error("socket failed");
  
  memset(&addr,0,sizeof(struct sockaddr_in));
  addr.sin_family = AF_INET;
  addr.sin_addr.s_addr = htonl(INADDR_ANY);
  addr.sin_port = htons(atoi(argv[2]));

  if (bind(sock, (struct sockaddr*)&addr,sizeof(addr))<0)
    die_error("bind failed");

  if (listen(sock,10))
    die_error("listen failed");

  int id = 1;
  
  while (1){
    int client_sock;

    if ((client_sock = accept(sock,NULL,NULL))<0)
      die_error("accept failed");

    if (fork()==0){
      char buffer[100];
      int sz;
      struct timeb tb;
      unsigned int start;
      unsigned int last_print;
      int read = 0,read_print = 0;

      //read everything from this sock and print it
      printf("New conn %d\n",id);
      ftime(&tb);
      start = tb.time*1000+tb.millitm;
      last_print = start;

      while ((sz = recv(client_sock,buffer,100,0))>0){
	unsigned int delta, elapsed,crt;
	//buffer[sz] = 0;
	//printf(buffer);
	read_print += sz;

	ftime(&tb);
	crt = tb.time*1000+tb.millitm;
	elapsed = crt-last_print;
	
	if (elapsed>1000){//read/100000!=(read+sz)/100000){
	  read += sz;
	  last_print = crt;
	  delta = last_print-start;

	  printf("[%d]=%.1fMB\t%.3f\t%u\t%.6f\n",id,(float)read/(1<<20),(float)read*1000/delta/(1<<20),crt,(float)read_print*1000/elapsed);
	  fflush(stdout);
	  read_print = 0;
	}
	else read += sz;
      }
      close(client_sock);
    }
    else {
      id++;
    }
  }
}
